package 力扣.栈;

import com.sun.media.sound.RIFFInvalidDataException;

import java.util.Stack;

/*
【题目】在水中有许多鱼，可以认为这些鱼停放在 x 轴上。再给定两个数组 Size，Dir，Size[i] 表示第 i 条鱼的大小，Dir[i] 表示鱼的方向 （0 表示向左游，1 表示向右游）。这两个数组分别表示鱼的大小和游动的方向，并且两个数组的长度相等。鱼的行为符合以下几个条件:

1、所有的鱼都同时开始游动，每次按照鱼的方向，都游动一个单位距离；

2、当方向相对时，大鱼会吃掉小鱼；

3、鱼的大小都不一样。

输入：Size = [4, 2, 5, 3, 1], Dir = [1, 1, 0, 0, 0]
输出：3

请完成以下接口来计算还剩下几条鱼？
int solution(int[] Size, int[] Dir);

请完成以下接口来计算还剩下几条鱼？*/
public class 大鱼吃小鱼问题 {
    public int solution(int[] fishSize, int[] fishDirection){
        // 首先拿到鱼的数量
        // 如果鱼的数量小于等于1，那么直接返回鱼的数量
        final int fishNumber = fishSize.length;
        if (fishNumber <= 1) {
            return fishNumber;
        }
        // 0表示鱼向左游
        final int left = 0;
        // 1表示鱼向右游
        final int right = 1;
        Stack<Integer> t = new Stack();
        for (int i = 0; i < fishNumber; i++) {
            // 当前鱼的情况：1，游动的方向；2，大小
            final int curFishDirection = fishDirection[i];
            final int curFishSize = fishSize[i];
            // 当前的鱼是否被栈中的鱼吃掉了
            boolean hasEat = false;
            // 如果栈中还有鱼，并且栈中鱼向右，当前的鱼向左游，那么就会有相遇的可能性
            while (!t.empty() && fishDirection[t.peek()] == right &&
                    curFishDirection == left) {
                // 如果栈顶的鱼比较大，那么把新来的吃掉
                if (fishSize[t.peek()] > curFishSize) {
                    hasEat = true;
                    break;
                }
                // 如果栈中的鱼较小，那么会把栈中的鱼吃掉，栈中的鱼被消除，所以需要弹栈。
                t.pop();
            }
            // 如果新来的鱼，没有被吃掉，那么压入栈中。
            if (!hasEat) {
                t.push(i);
            }
        }
        return t.size();
    }
    public static int solution2(int[] A, int[] B) {
        Stack<Integer> stack = new Stack();
        for (int i = 0; i < A.length; i++) {
            int size = A[i];
            int direction = B[i];
            boolean beEated = false;
            while (!stack.isEmpty() && B[stack.peek()] != direction){
                if (B[stack.peek()] == 1 && direction == 0){
                    if (A[stack.peek()] < size){
                        stack.pop();
                    }else {
                        beEated = true;
                        break;
                    }
                }
            }
            if (!beEated){
                stack.push(i);
            }
        }
        return stack.size();
    }



    public int solution3(int[] fishSize, int[] fishDirection){
          if (fishSize == null){
              return 0;
          }
          Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < fishSize.length; i++) {
            //当前鱼的大小和方向
            int teSize = fishSize[i];
            int teDir = fishDirection[i];

            boolean isEat = false;//当前鱼是否被吃了
            while(!stack.isEmpty()){//一直弹，直到满足条件
                //栈中鱼的大小和方向
                Integer pre = stack.peek();
                int preSize = fishSize[pre];
                int preDir = fishDirection[pre];

                if (preDir == 1 && teDir == 0){//方向相对
                    if (preSize < teSize){//栈中的鱼被吃掉
                        stack.pop();
                    }else {//当前的鱼被吃掉
                        isEat = true;
                        break;
                    }
                }

            }
            if (!isEat){
                stack.push(i);
            }

        }
        return stack.size();
    }
}
